extern crate winapi;

use std::ptr::null_mut;
use winapi::ctypes::{c_void};
use winapi::shared::minwindef::{LPARAM, WPARAM};
use winapi::shared::windef::HWND;
use winapi::um::winuser::{
    CallNextHookEx, SetWindowsHookEx, UnhookWindowsHookEx, WH_MOUSE_LL,
    MSLLHOOKSTRUCT, GetAsyncKeyState,
};

// 鼠标钩子的回调函数
extern "system" fn mouse_hook(ncode: i32, wparam: WPARAM, lparam: LPARAM) -> i32 {
    if ncode >= 0 {
        unsafe {
            let mouse_hook_struct: &MSLLHOOKSTRUCT = &*(lparam as *const MSLLHOOKSTRUCT);
            println!("Mouse at x: {}, y: {}", mouse_hook_struct.pt.x, mouse_hook_struct.pt.y);
        }
    }
    unsafe { CallNextHookEx(null_mut(), ncode, wparam, lparam) }
}

fn main() {
    // 安装鼠标钩子
    let hook = unsafe {
        SetWindowsHookEx(WH_MOUSE_LL, Some(mouse_hook), null_mut(), 0)
    };

    if hook.is_null() {
        eprintln!("Failed to set hook.");
        return;
    }

    println!("Mouse hook is set. Press 'q' to exit...");

    loop {
        let mut key_state = unsafe { GetAsyncKeyState('q' as i32) };
        if key_state & 0x8000 != 0 {
            break;
        }
    }

    // 卸载钩子
    unsafe {
        UnhookWindowsHookEx(hook);
    }

    println!("Mouse hook has been removed.");
}